/***
 * Copyright (c) 2021-2031 murenchao
 * fig is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *       http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package cool.taomu.software.fig.mqtt.utils

import io.netty.buffer.ByteBuf
import io.netty.channel.Channel
import io.netty.handler.codec.mqtt.MqttMessage
import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader
import io.netty.util.AttributeKey
import java.nio.ByteBuffer
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory

class CommonUtils{

    static val AttributeKey<String> clientIdAttr = AttributeKey.valueOf("CLIENT_ID");
    static ExecutorService exec = Executors.newCachedThreadPool(new ThreadFactory() {
        override newThread(Runnable r) {
            return new Thread(r);
        }
    });

    def static exec(Runnable r) {
        exec.submit(r);
    }

    def static shutdown() {
        if(!exec.isShutdown){
            exec.shutdown();
        }
    }

    def static void setClientId(Channel channel, String clientId) {
        channel.attr(clientIdAttr).set(clientId);
    }

    def static String getClientId(Channel channel) {
        return channel.attr(clientIdAttr).get();
    }

    def static readBytesFromByteBuf(ByteBuf byteBuf) {
        var bb = ByteBuffer.allocate(byteBuf.readableBytes());
        byteBuf.readBytes(bb);
        return bb.array;
    }

    def static getMessageId(MqttMessage mqttMessage) {
        var varHeader = mqttMessage.variableHeader() as MqttMessageIdVariableHeader;
        return varHeader.messageId();
    }

    def static getQos(int qos1, int qos2) {
        if (qos1 < qos2) {
            return qos1;
        }
        return qos2;
    }

    def static String getRemoteAddr(Channel channel) {
        if (null === channel) {
            return "";
        }
        var remote = channel.remoteAddress();
        val addr = remote !== null ? remote.toString() : "";
        if (addr.length() > 0) {
            var index = addr.lastIndexOf("/");
            if (index >= 0) {
                return addr.substring(index + 1);
            }
            return addr;
        }
        return "";
    }

}
